package org.PISS.DAO;

import org.PISS.controller.model.*;
import org.PISS.utils.HibernateUtil;
import org.hibernate.Query;
import org.hibernate.Session;
import org.PISS.controller.model.Fieldset;

import java.util.List;
import java.util.Map;

/**
 * Created by admin on 27.12.13.
 */
public class ProductDAO {

    public static final String INTEGER_TABLE="INTEGER_TABLE";
    public static final String DOUBLE_TABLE="DOUBLE_TABLE";
    public static final String TEXT_TABLE="TEXT_TABLE";
    public static final String MONEY_TABLE="MONEY_TABLE";

    public Product getProductById(Long id){

        if(id==null)return null;

        Session session=null;
        Product product=null;

        try{
            session = HibernateUtil.getSessionFactory().openSession();
            product=(Product)session.get(Product.class, id);
        }catch (Exception e){
            throw  new RuntimeException("Getting exception",e);
        }
        finally {
            if (session != null && session.isOpen()) {
                session.close();
            }
        }
        return product;
    }

    public ProductType getProductTypeByID(Long id){
        if(id==null)return null;

        Session session=null;
        ProductType productType=null;

        try{
            session = HibernateUtil.getSessionFactory().openSession();
            productType=(ProductType)session.get(ProductType.class, id);
        }catch (Exception e){
            throw  new RuntimeException("Getting exception",e);
        }
        finally {
            if (session != null && session.isOpen()) {
                session.close();
            }
        }
        return productType;
    }

    public ProductType getProductType(long productID){
        Session session = null;
        List<ProductType> typeList=null;
        try{
            Query query = session.createQuery("select new ProductType(t.typeID, t.name, t.description)" +
                    " from ProductType t, Product p " +
                    "where p.typeId=t.typeID and p.productID= :prodID").setLong("prodID",productID).setMaxResults(1);
            //noinspection unchecked
            typeList=(List<ProductType>)query.list();
        }catch (Exception e){
            throw new RuntimeException("Save exception",e);
        }finally {
            if (session != null && session.isOpen()) {
                session.close();
            }
        }
        return typeList.get(0);
    }

    public List<Product> getProductsByType(long productTypeId){

        Session session = null;
        List<Product> productList=null;
        try{
            session = HibernateUtil.getSessionFactory().openSession();
            session.beginTransaction();
            Query query = session.createQuery("FROM Product WHERE typeId=:productTypeId").setLong("productTypeId",productTypeId);
            //noinspection unchecked
            productList=query.list();
        }catch (Exception e){
            throw new RuntimeException("Save exception",e);
        }finally {
            if (session != null && session.isOpen()) {
                session.close();
            }
        }
        return productList;
    }

    public void addProduct(Product product){
       DAOUtils.add(product);
    }

    public void addProducts(List<Product> productList){
        DAOUtils.add(productList);
    }

    public void addProductType(ProductType type){
        DAOUtils.add(type);
    }

    public List<Fieldset> getFieldsets(long productTypeId){
        Session session = null;
        List<Fieldset> fieldsetList=null;
        try{
            session = HibernateUtil.getSessionFactory().openSession();
            session.beginTransaction();
            Query query = session.createQuery("FROM Fieldset WHERE Fieldset.producrTypeId=:typeId").setLong("typeId",productTypeId);
            fieldsetList=query.list();
        }catch (Exception e){
            throw new RuntimeException("Getting exception",e);
        }finally {
            if (session != null && session.isOpen()) {
                session.close();
            }
        }
        return fieldsetList;
    }

    public Field getField(long productId, Fieldset fieldset){
        Session session = null;
        Field field=null;
        try{
            session = HibernateUtil.getSessionFactory().openSession();
            session.beginTransaction();
            if(ProductDAO.INTEGER_TABLE.equalsIgnoreCase(fieldset.getDataTable())){
                Query query = session.createQuery("select new IntegerField(field.id, field.productId, field.fieldsetId, field.description)" +
                        " from IntegerField field " +
                        "where field.productId=:product and field.fieldsetId=:fieldset").setLong("product",productId).setLong("fieldset",fieldset.getFieldsetId());
                field=(IntegerField)query.list().get(0);
            }
            else if(ProductDAO.DOUBLE_TABLE.equalsIgnoreCase(fieldset.getDataTable())){
                Query query = session.createQuery("select new DoubleField(field.id, field.productId, field.fieldsetId, field.description)" +
                        " from DoubleField field " +
                        "where field.productId=:product and field.fieldsetId=:fieldset").setLong("product",productId).setLong("fieldset",fieldset.getFieldsetId());
                field=(DoubleField)query.list().get(0);
            }
            else if(ProductDAO.MONEY_TABLE.equalsIgnoreCase(fieldset.getDataTable())){
                Query query = session.createQuery("select new MoneyField(field.id, field.productId, field.fieldsetId, field.description)" +
                        " from MoneyField field " +
                        "where field.productId=:product and field.fieldsetId=:fieldset").setLong("product",productId).setLong("fieldset",fieldset.getFieldsetId());
                field=(MoneyField)query.list().get(0);
            }
            else if(ProductDAO.TEXT_TABLE.equalsIgnoreCase(fieldset.getDataTable())){
                Query query = session.createQuery("select new TextField(field.id, field.productId, field.fieldsetId, field.description)" +
                        " from TextField field " +
                        "where field.productId=:product and field.fieldsetId=:fieldset").setLong("product",productId).setLong("fieldset",fieldset.getFieldsetId());
                field=(TextField)query.list().get(0);
            }
            else throw new Exception("Unsupported Data Table");
        }catch (Exception e){
            throw new RuntimeException("Getting exception",e);
        }finally {
            if (session != null && session.isOpen()) {
                session.close();
            }
        }
        return field;
    }

    public List<Product> getProducts(){
        Session session = null;
        List<Product> productList=null;
        try{
            session = HibernateUtil.getSessionFactory().openSession();
            session.beginTransaction();
            Query query = session.createQuery("FROM Product");
            //noinspection unchecked
            productList=query.list();
        }catch (Exception e){
            throw new RuntimeException("Save exception",e);
        }finally {
            if (session != null && session.isOpen()) {
                session.close();
            }
        }
        return productList;
    }

    public List<ProductType> getProductTypes(){
        Session session = null;
        List<ProductType> typeList=null;
        try{
            session = HibernateUtil.getSessionFactory().openSession();
            session.beginTransaction();
            Query query = session.createQuery("FROM ProductType ");
            //noinspection unchecked
            typeList=query.list();
        }catch (Exception e){
            throw new RuntimeException("Save exception",e);
        }finally {
            if (session != null && session.isOpen()) {
                session.close();
            }
        }
        return typeList;
    }

    public List<Product> getContainsProducts(long productID){
        Session session =  null;
        List<Product> productList=null;
        try{
            session = HibernateUtil.getSessionFactory().openSession();
            session.beginTransaction();
            Query query = session.createQuery("select new Product(p.productID, p.typeId, p.name, p.description, p.qualityRating)" +
                    " from Product p, ProductContains pc " +
                    "where p.productID=pc.containsProductID and pc.productID= :prodID").setLong("prodID",productID);
            //noinspection unchecked
            productList=(List<Product>)query.list();
        }catch (Exception e){
            throw new RuntimeException("Save exception",e);
        }finally {
            if (session != null && session.isOpen()) {
                session.close();
            }
        }
        return productList;
    }

    public void addProductContains(List<ProductContains> productContainsList){
        Session session = null;
        try {
            session = HibernateUtil.getSessionFactory().openSession();
            session.beginTransaction();
            if (productContainsList!=null&&!productContainsList.isEmpty()){
                for(ProductContains productContain:productContainsList)
                    session.save(productContain);
            }
            session.getTransaction().commit();
        } catch (Exception e) {
            throw new RuntimeException("Save exception",e);
        } finally {
            if (session != null && session.isOpen()) {
                session.close();
            }
        }
    }
}
